package LeetCode;

import java.awt.desktop.OpenFilesHandler;

/**
 * 删除链表中所有值为val的节点。
 */
public class _203 {
}

class ListNode {
    int val;
    ListNode next;

    ListNode() {
    }

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }

    /**
     *liuyubobobo教的自己创建测试用例的方法。是通过添加一个节点的构造函数实现的。
     * 这个构造函数接收一个int数组，返回由这个数组组成的链表。表头就是第一个数的节点。
     * @param arr
     */
    ListNode(int[] arr) {
        if(arr == null || arr.length == 0) //没考虑arr==null的情况
            throw new IllegalArgumentException();
        this.val = arr[0]; //头开始还在写return语句呢。这是构造器函数，不能return。this就是指向本对象的指针，要想操作就在this上操作。
        ListNode tail = this;
        for (int i = 1; i < arr.length; i++) {
           tail.next  = new ListNode(arr[i],null);
           tail = tail.next;
        }
    }

    /**
     * 返回以this为头节点的链表的字符表示。
     * @return
     */
    @Override
    public String toString() {
       StringBuilder res = new StringBuilder();
       ListNode cur = this;
        while (cur != null) {
            res.append(cur.val + "->");
            cur = cur.next;
        }
        res.append("Null");
        return res.toString();
    }
}


class Solution {
    /**
     * 删除head中所有val为val的节点，返回删除后的链表头节点。
     * @param head
     * @param val
     * @return
     */
    public ListNode removeElements(ListNode head, int val) {
        while (head != null && head.val == val)
            head = head.next;
        if (head == null)
            return null;
        ListNode pre = head;
        while (pre.next != null) {
            if (pre.next.val == val)
                pre.next = pre.next.next;
            else
                pre = pre.next;
        }
        return head;
    }

    /**
     * 递归版本。
     * @param head
     * @param val
     * @return
     */
    public ListNode remove2(ListNode head, int val,int depth) {

        System.out.printf("%s, Call: remove %d in %s\n",generateDepthString(depth),val,head);
        if(head == null){
            System.out.printf("%s, Return: After remove %d in %s is %s\n",generateDepthString(depth),val,head,head);
            return null;
        }
        ListNode res= remove2(head.next, val,depth + 1);
        ListNode originHead = head;
        if(head.val == val)
            head = res;
        else
            head.next = res;
        System.out.printf("%s, Return: After remove %d in %s is %s\n",generateDepthString(depth),val, originHead,head);
        return head;
    }

    private String  generateDepthString(int depth) {
        StringBuilder res = new StringBuilder();
        res.append("Depth: " + depth);
        for(int i = 0;i<depth;i++)
            res.append("--");
        return res.toString();
    }

    /**
     * 正向打印输出链表。递归版本。
     * @param head
     */
    public void printList(ListNode head) {
        if(head ==null) {
            System.out.print("Null");
            return;
        }
        System.out.print(head.val + "->");
        printList(head.next);
    }

    public void printListReversed(ListNode head) {
        if(head == null) {
            System.out.print("Null->");
            return;
        }
        printListReversed(head.next);
        System.out.printf("%s->",head.val);
    }
    public static void main(String[] args) {
        int [] nums = {1, 2, 6, 3, 4, 5, 6};
        ListNode head = new ListNode(nums);
        Solution solution = new Solution();
        System.out.println(head);
        solution.remove2(head,6,1);
    }
}